const { AchievementDefinition, UserAchievement } = require('./model');
const { Op } = require('sequelize');

class AchievementDao {
  // 成就定义相关操作
  
  // 创建成就定义
  async createAchievementDefinition(achievementData) {
    try {
      return await AchievementDefinition.create(achievementData);
    } catch (error) {
      throw new Error(`创建成就定义失败: ${error.message}`);
    }
  }

  // 获取所有成就定义
  async getAllAchievementDefinitions(options = {}) {
    try {
      const { page = 1, limit = 10, category, type, is_active } = options;
      const offset = (page - 1) * limit;
      
      const whereClause = {};
      if (category) whereClause.category = category;
      if (type) whereClause.type = type;
      if (is_active !== undefined) whereClause.is_active = is_active;

      const { count, rows } = await AchievementDefinition.findAndCountAll({
        where: whereClause,
        order: [['sort', 'ASC'], ['created_at', 'DESC']],
        limit: parseInt(limit),
        offset: parseInt(offset)
      });

      return {
        achievements: rows,
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(count / limit)
      };
    } catch (error) {
      throw new Error(`获取成就定义列表失败: ${error.message}`);
    }
  }

  // 根据ID获取成就定义
  async getAchievementDefinitionById(id) {
    try {
      return await AchievementDefinition.findByPk(id);
    } catch (error) {
      throw new Error(`获取成就定义失败: ${error.message}`);
    }
  }

  // 根据键值获取成就定义
  async getAchievementDefinitionByKey(key) {
    try {
      return await AchievementDefinition.findOne({ where: { key } });
    } catch (error) {
      throw new Error(`获取成就定义失败: ${error.message}`);
    }
  }

  // 更新成就定义
  async updateAchievementDefinition(id, updateData) {
    try {
      const [updatedRowsCount] = await AchievementDefinition.update(updateData, {
        where: { id }
      });
      
      if (updatedRowsCount === 0) {
        throw new Error('成就定义不存在');
      }
      
      return await this.getAchievementDefinitionById(id);
    } catch (error) {
      throw new Error(`更新成就定义失败: ${error.message}`);
    }
  }

  // 删除成就定义
  async deleteAchievementDefinition(id) {
    try {
      const deletedRowsCount = await AchievementDefinition.destroy({
        where: { id }
      });
      
      if (deletedRowsCount === 0) {
        throw new Error('成就定义不存在');
      }
      
      return true;
    } catch (error) {
      throw new Error(`删除成就定义失败: ${error.message}`);
    }
  }

  // 用户成就相关操作

  // 为用户授予成就
  async grantUserAchievement(userId, achievementKey, progressData = {}) {
    try {
      const achievementDef = await this.getAchievementDefinitionByKey(achievementKey);
      if (!achievementDef) {
        throw new Error('成就定义不存在');
      }

      const userAchievementData = {
        user_id: userId,
        achievement_key: achievementKey,
        achievement_name: achievementDef.name,
        description: achievementDef.description,
        icon: achievementDef.icon,
        badge_color: achievementDef.badge_color,
        points: achievementDef.points,
        experience: achievementDef.experience,
        progress: progressData
      };

      return await UserAchievement.create(userAchievementData);
    } catch (error) {
      throw new Error(`授予用户成就失败: ${error.message}`);
    }
  }

  // 获取用户所有成就
  async getUserAchievements(userId, options = {}) {
    try {
      const { page = 1, limit = 10 } = options;
      const offset = (page - 1) * limit;

      const { count, rows } = await UserAchievement.findAndCountAll({
        where: { user_id: userId },
        order: [['earned_at', 'DESC']],
        limit: parseInt(limit),
        offset: parseInt(offset)
      });

      return {
        achievements: rows,
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(count / limit)
      };
    } catch (error) {
      throw new Error(`获取用户成就失败: ${error.message}`);
    }
  }

  // 检查用户是否已获得某个成就
  async hasUserAchievement(userId, achievementKey) {
    try {
      const achievement = await UserAchievement.findOne({
        where: {
          user_id: userId,
          achievement_key: achievementKey
        }
      });
      return !!achievement;
    } catch (error) {
      throw new Error(`检查用户成就失败: ${error.message}`);
    }
  }

  // 获取用户成就统计
  async getUserAchievementStats(userId) {
    try {
      const totalAchievements = await AchievementDefinition.count({
        where: { is_active: true }
      });
      
      const earnedAchievements = await UserAchievement.count({
        where: { user_id: userId }
      });

      const totalPoints = await UserAchievement.sum('points', {
        where: { user_id: userId }
      }) || 0;

      const totalExperience = await UserAchievement.sum('experience', {
        where: { user_id: userId }
      }) || 0;

      return {
        totalAchievements,
        earnedAchievements,
        completionRate: totalAchievements > 0 ? (earnedAchievements / totalAchievements * 100).toFixed(2) : 0,
        totalPoints,
        totalExperience
      };
    } catch (error) {
      throw new Error(`获取用户成就统计失败: ${error.message}`);
    }
  }

  // 删除用户成就
  async removeUserAchievement(userId, achievementKey) {
    try {
      const deletedRowsCount = await UserAchievement.destroy({
        where: {
          user_id: userId,
          achievement_key: achievementKey
        }
      });
      
      if (deletedRowsCount === 0) {
        throw new Error('用户成就不存在');
      }
      
      return true;
    } catch (error) {
      throw new Error(`删除用户成就失败: ${error.message}`);
    }
  }
}

module.exports = new AchievementDao();
